package com.regex.web.generate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

/**
 * 代码生成器
 * @author ocean.regex
 *
 */
public class MpGenerator {
	
	public static void main(String[] args) {
		// 货款流水
//		createCode("t_goods_account_flow", "member", "t_");
		// 返利账户流水
//		createCode("t_rebate_account_flow", "member", "t_");
		// 提现申请
//		createCode("t_rebate_apply", "member", "t_");
		// 统计率
//		createCode("t_count_config", "conut", "t_");
		// 月度统计表
//		createCode("t_month_count", "conut", "t_");
		// 模板消息绑定表
//		createCode("t_model_message_bind", "message", "t_");
		// 保证金流水
//		createCode("t_member_bond_flow", "member", "t_");
		
//		createCode("t_discount_active", "activity", "t_");
	    
//	    createCode("t_express_company", "order", "t_");
		
		// member
//	    createCode("t_member_info", "member", "t_");
//	    
//		createCode("t_nurse_info", "member", "t_");
//		// area
//		createCode("t_open_city", "area", "t_");
//		createCode("t_city_county", "area", "t_");
//		createCode("gen_field_info", "gen", "gen_");
//		createCode("gen_table_info", "gen", "gen_");
//		createCode("gen_database", "gen", "gen_");
		createCode("t_member_card", "member", "t_");
//		getTableInfo();
	}
	
	public List<TableInfo> getTableInfo() {
		AutoGenerator mpg = new AutoGenerator();
		
		 GlobalConfig gc = new GlobalConfig();
	      gc.setIdType(IdType.ID_WORKER_STR);
		
		DataSourceConfig dsc = new DataSourceConfig();
	      dsc.setDbType(DbType.MYSQL);
	      dsc.setTypeConvert(new MySqlTypeConvert() {
	          // 自定义数据库表字段类型转换【可选】
	          public DbColumnType processTypeConvert(String fieldType) {
	              System.out.println("转换类型：" + fieldType);
	              // 注意！！processTypeConvert 存在默认类型转换，如果不是你要的效果请自定义返回、非如下直接返回。
	              return (DbColumnType) super.processTypeConvert(gc, fieldType);
	          }
	      });
	      dsc.setDriverName("com.mysql.jdbc.Driver");
	      dsc.setUsername("root");
	      dsc.setPassword("123456");
	      dsc.setUrl("jdbc:mysql://127.0.0.1:3306/base_db?useUnicode=true&characterEncoding=utf8");
	      mpg.setDataSource(dsc);
	      
	      StrategyConfig strategy = new StrategyConfig();
	      
	      strategy.setTablePrefix(new String[] { "t_" });// 此处可以修改为您的表前缀
	      strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
	      
//	      strategy.setInclude(new String[] { "t_member_card" });
	      
	      strategy.setSuperEntityColumns(new String[] { "id", "is_del", "create_time", "update_time" });
	      
	      mpg.setStrategy(strategy);
	      
//	      mpg.execute();
	      ConfigBuilder  config = new ConfigBuilder(new PackageConfig(), dsc, strategy, new TemplateConfig(), gc);
	      List<TableInfo> tableList = mpg.getAllTableInfoList(config);
	      System.out.println(tableList.size());
//	      System.out.println(JSON.toJSONString(tableList));
	      return tableList;
	}
	
	
	public static void createCode(String tableName, String packageName, String prefix) {
//      assert (false) : "代码生成属于危险操作，请确定配置后取消断言执行代码生成！";
      AutoGenerator mpg = new AutoGenerator();
      // 选择 freemarker 引擎，默认 Velocity
      mpg.setTemplateEngine(new FreemarkerTemplateEngine());
      // 全局配置
      GlobalConfig gc = new GlobalConfig();
      /**
       * 设置id为全局唯一变量
       */
      gc.setIdType(IdType.ID_WORKER_STR);
//      gc.seti
      gc.setAuthor("ocean.ma");
      gc.setOutputDir("D://workspace/src/main/java");
      gc.setFileOverride(true);// 是否覆盖同名文件，默认是false
      gc.setActiveRecord(true);// 不需要ActiveRecord特性的请改为false
      gc.setEnableCache(false);// XML 二级缓存
      gc.setBaseResultMap(true);// XML ResultMap
      gc.setBaseColumnList(false);// XML columList
      /* 自定义文件命名，注意 %s 会自动填充表实体属性！ */
      gc.setEntityName("%sDTO");
       gc.setMapperName("%sDAO");
      // gc.setXmlName("%sDao");
      // gc.setServiceName("MP%sService");
      // gc.setServiceImplName("%sServiceDiy");
      // gc.setControllerName("%sAction");
       mpg.setGlobalConfig(gc);
      

      // 数据源配置
      DataSourceConfig dsc = new DataSourceConfig();
      dsc.setDbType(DbType.MYSQL);
      dsc.setTypeConvert(new MySqlTypeConvert() {
          // 自定义数据库表字段类型转换【可选】
          public DbColumnType processTypeConvert(String fieldType) {
              System.out.println("转换类型：" + fieldType);
              // 注意！！processTypeConvert 存在默认类型转换，如果不是你要的效果请自定义返回、非如下直接返回。
              return (DbColumnType) super.processTypeConvert(gc, fieldType);
          }
      });
      dsc.setDriverName("com.mysql.jdbc.Driver");
      dsc.setUsername("root");
      dsc.setPassword("123456");
      dsc.setUrl("jdbc:mysql://127.0.0.1:3306/base_db?useUnicode=true&characterEncoding=utf8");
      mpg.setDataSource(dsc);

      // 策略配置
      StrategyConfig strategy = new StrategyConfig();
      // strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意
      strategy.setTablePrefix(new String[] { prefix });// 此处可以修改为您的表前缀
      strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
//      strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//      strategy.setEntityLombokModel(true);
      strategy.setInclude(new String[] { tableName }); // 需要生成的表
//      strategy.setLogicDeleteFieldName("is_del");
      // strategy.setExclude(new String[]{"test"}); // 排除生成的表
      // 自定义实体父类
       strategy.setSuperEntityClass("com.regex.web.entity.StrIdBaseEntity");
      // 自定义实体，公共字段
       strategy.setSuperEntityColumns(new String[] { "id", "is_del", "create_time", "update_time" });
//      strategy.setcol
      // 自定义 mapper 父类
      // strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
      // 自定义 service 父类
       strategy.setSuperServiceClass("com.regex.web.service.base.IBaseService");
//       自定义 service 实现类父类
       strategy.setSuperServiceImplClass("com.regex.web.service.base.impl.BaseServiceImpl");
      // 自定义 controller 父类
//       strategy.setSuperControllerClass("com.baomidou.demo.TestController");
      // 【实体】是否生成字段常量（默认 false）
      // public static final String ID = "test_id";
//       strategy.setEntityColumnConstant(true);
      // 【实体】是否为构建者模型（默认 false）
      // public User setName(String name) {this.name = name; return this;}
//       strategy.setEntityBuilderModel(true);
       // 添加字段注解
       strategy.entityTableFieldAnnotationEnable(true);
      mpg.setStrategy(strategy);

      // 包配置
      PackageConfig pc = new PackageConfig();
//      pc.setModuleName("test");
//      String packageName = "member";
      pc.setParent("com.regex.web");
      pc.setEntity("entity." + packageName);
      pc.setService("service." + packageName);
      pc.setServiceImpl("service."+ packageName + ".impl");
      pc.setMapper("dao." + packageName);
      pc.setXml("dao." + packageName);
      pc.setController("controller." + packageName);
      // pc.setModuleName("test");
      mpg.setPackageInfo(pc);

      // 注入自定义配置，可以在 VM 中使用 cfg.abc 【可无】
       InjectionConfig cfg = new InjectionConfig() {
       @Override
       public void initMap() {
       Map<String, Object> map = new HashMap<String, Object>();
       map.put("abc", this.getConfig().getGlobalConfig().getAuthor() +
       "-mp");
       this.setMap(map);
       }
       };
      
       // 自定义 xxList.jsp 生成
       List<FileOutConfig> focList = new ArrayList<>();
       
       focList.add(new FileOutConfig("/templates/template/list.html.ftl") {
       @Override
       public String outputFile(TableInfo tableInfo) {
       // 自定义输入文件名称
       return "D://workspace/src/main/java/page/" + tableInfo.getEntityPath().substring(0, tableInfo.getEntityPath().length() - 3) + "/show.html";
       }
       });
       cfg.setFileOutConfigList(focList);
       mpg.setCfg(cfg);
//      
//       // 调整 xml 生成目录演示
       focList.add(new FileOutConfig("/templates/template/input.html.ftl") {
       @Override
       public String outputFile(TableInfo tableInfo) {
       return "D://workspace/src/main/java/page/" + tableInfo.getEntityPath().substring(0, tableInfo.getEntityPath().length() - 3) + "/input.html";
       }
       });
       cfg.setFileOutConfigList(focList);
       mpg.setCfg(cfg);
       
       focList.add(new FileOutConfig("/templates/template/detial.html.ftl") {
           @Override
           public String outputFile(TableInfo tableInfo) {
           return "D://workspace/src/main/java/page/" + tableInfo.getEntityPath().substring(0, tableInfo.getEntityPath().length() - 3) + "/detial.html";
           }
           });
       
       focList.add(new FileOutConfig("/templates/template/restcontroller.java.ftl") {
           @Override
           public String outputFile(TableInfo tableInfo) {
           return "D://workspace/src/main/java/page/" + "/" + tableInfo.getParentPackage().replaceAll("\\.", "\\/") + "/rest/" + tableInfo.getPackageName() + "/" + tableInfo.getEntityName().substring(0, tableInfo.getEntityPath().length() - 3) + "RestController.java";
           }
           });
           cfg.setFileOutConfigList(focList);
           mpg.setCfg(cfg);
      //
      // // 关闭默认 xml 生成，调整生成 至 根目录
       TemplateConfig tc = new TemplateConfig();
      // tc.setXml(null);
      // mpg.setTemplate(tc);

      // 自定义模板配置，可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改，
      // 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置，也可以自定义模板名称
      // TemplateConfig tc = new TemplateConfig();
       tc.setController("/templates/template/controller.java");
       tc.setEntity("/templates/template/entity.java");
       tc.setMapper("/templates/template/mapper.java");
       tc.setXml("/templates/template/mapper.xml");
       tc.setService("/templates/template/service.java");
       tc.setServiceImpl("/templates/template/serviceImpl.java");
      // 如上任何一个模块如果设置 空 OR Null 将不生成该模块。
       mpg.setTemplate(tc);

      // 执行生成
      mpg.execute();

      // 打印注入设置【可无】
      // System.err.println(mpg.getCfg().getMap().get("abc"));
	}

}
